package com.suke.czx.modules.wx.controller;

import java.io.IOException;
import java.io.OutputStream;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import org.apache.commons.lang3.StringUtils;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;

import com.alibaba.fastjson.JSONObject;
import com.google.zxing.BarcodeFormat;
import com.google.zxing.EncodeHintType;
import com.google.zxing.MultiFormatWriter;
import com.google.zxing.WriterException;
import com.google.zxing.client.j2se.MatrixToImageWriter;
import com.google.zxing.common.BitMatrix;
import com.google.zxing.qrcode.decoder.ErrorCorrectionLevel;
import com.suke.czx.common.utils.DateUtils;
import com.suke.czx.common.utils.JsonResult;
import com.suke.czx.common.utils.RedisUtils;
import com.suke.czx.common.utils.UUIDS;
import com.suke.czx.modules.wx.config.WxMpConfiguration;
import com.suke.czx.modules.wx.config.WxPayProperties;
import com.suke.czx.modules.wx.cons.Constant;
import com.suke.czx.modules.wx.vo.UserReadDays;
import com.suke.czx.modules.wxadmin.entity.DkCourseEntity;
import com.suke.czx.modules.wxadmin.entity.DkDisEntity;
import com.suke.czx.modules.wxadmin.entity.DkDomianEntity;
import com.suke.czx.modules.wxadmin.entity.DkReadPlanEntity;
import com.suke.czx.modules.wxadmin.entity.DkResourceEntity;
import com.suke.czx.modules.wxadmin.entity.DkUserEntity;
import com.suke.czx.modules.wxadmin.service.DkCourseService;
import com.suke.czx.modules.wxadmin.service.DkDisService;
import com.suke.czx.modules.wxadmin.service.DkDomianService;
import com.suke.czx.modules.wxadmin.service.DkReadPlanService;
import com.suke.czx.modules.wxadmin.service.DkResourceService;
import com.suke.czx.modules.wxadmin.service.DkUserService;

import me.chanjar.weixin.mp.api.WxMpService;
import me.chanjar.weixin.mp.bean.result.WxMpQrCodeTicket;
import me.chanjar.weixin.mp.bean.result.WxMpUser;

@RestController
@RequestMapping("/wx/course/{appid}")
public class WxCourseConntller extends BaseController{
	
	@Autowired
	private DkUserService dkUserService;
	@Autowired
	private DkResourceService dkResourceService;
	@Autowired 
	private DkReadPlanService dkReadPlanService;
	@Autowired
	private DkCourseService dkCourseService;
	@Autowired
	private DkDisService dkDisService;
	
	@Autowired 
	private DkDomianService dkDomianService;
	@Autowired
	private RedisUtils redisUtils;
	
	@Autowired 
	private WxPayProperties wxPayProperties;
	
	
	private org.slf4j.Logger logger = LoggerFactory.getLogger(getClass());
	
	
	
	@RequestMapping(value="/course")
	public String course(@PathVariable String appid , @RequestParam(defaultValue="1")Integer cid,@RequestParam(defaultValue="1")String dis){
		DkCourseEntity dc  = dkCourseService.queryObject(cid);
		if(!dis.equals("1")){
			DkDisEntity dkdis =dkDisService.queryObject(dis);
			if(null!=dkdis){
				dc.setPriceOff(dkdis.getDisPrice());
			}
		}
		return new JsonResult(200,"ok",dc).toJson();
	}
	@RequestMapping(value="/inv")
	public String invitation(@PathVariable String appid , @RequestParam(defaultValue="1")Integer cid,@RequestParam(defaultValue="1")String dis){
		DkCourseEntity dc  = dkCourseService.queryObject(cid);
		Map<String , Object> map = new HashMap<>();
		map.put("course", dc);
		logger.info("=========>inv dis  : " + dis);
		map.put("inv_user", null);
		map.put("users", new ArrayList<>());
		if(!dis.equals("1")&&dis.length()>20){
			//1、或者去邀请者信息
			DkUserEntity inv_user = dkUserService.queryObject(dis,false);
			logger.info("=========>inv dis  : " + inv_user.getHeadimg());
			if(null!=inv_user){
				List<DkUserEntity> users = dkUserService.queryInvUser(dis);
				map.put("inv_user", inv_user);
				map.put("users", users);
			}
		}
		return new JsonResult(200,"ok",map).toJson();
	}
	
	
	
	@RequestMapping(value="/complete/learning")
	public String complete_learning(){
		WxMpUser wxMpUser = (WxMpUser) getSession().getAttribute(Constant.WX_USER);
		if(null==wxMpUser){
			return new JsonResult(24,"用户未登录，请先登录！").toJson();
		}
		DkUserEntity dkUser = dkUserService.queryObject(wxMpUser.getOpenId(),true);
		if(dkUser.getState()==0){
			return new JsonResult(23,"用户未订购，请跳转购买链接！").toJson();
		}
		List<DkResourceEntity> list = dkResourceService.queryComplet(wxMpUser.getOpenId());
		return new JsonResult(200,"ok",list).toJson();
	}
	
	
	
	@RequestMapping(value="/resource_list")
	public String resource_list(){
		Map<String, Object> params = new HashMap<String, Object>();
		params.put("page", 1);
		params.put("limit", 1000);
		List<DkResourceEntity> list = dkResourceService.queryList(params);
		return new JsonResult(200,"ok",list).toJson();
	}
	

	@RequestMapping(value="/resource_detail")
	public String resource_detail( Integer id){
//		WxMpUser wxMpUser = (WxMpUser) getSession().getAttribute(Constant.WX_USER);
//		if(null==wxMpUser){
//			return new JsonResult(24,"用户未登录，请先登录！").toJson();
//		}
//		DkUserEntity dkUser = dkUserService.queryObject(wxMpUser.getOpenId());
//		if(dkUser.getState()==0){
//			return new JsonResult(23,"用户未订购，请跳转购买链接！").toJson();
//		}
		return new JsonResult(200,"ok",dkResourceService.queryObject(id)).toJson();
	}
	
	
	
	@RequestMapping(value="/read")
	public String read(@PathVariable String appid,String dateStr ,String openid){
		WxMpUser wxMpUser = (WxMpUser) getSession().getAttribute(Constant.WX_USER);
		if(null==wxMpUser){
			return new JsonResult(24,"用户未登录，请先登录！").toJson();
		}
		DkUserEntity dkUser = dkUserService.queryObject(wxMpUser.getOpenId(),true);
		if(dkUser.getState()==0){
			return new JsonResult(23,"用户未订购，请跳转购买链接！").toJson();
		}
		boolean f = false;
		String tmp_DateStr = DateUtils.format(new Date(), DateUtils.DATE_PATTERN);
		
		if(StringUtils.isEmpty(dateStr)){
			dateStr = tmp_DateStr;
			f=true;
		}else if(dateStr.equals(tmp_DateStr)){
			f=true;
		}
		
		Map<String,Object> result  = redisUtils.getObject("memread_"+openid+"_"+dateStr);
		if(null!=result){
			return new JsonResult(200,"ok",result).toJson();
		}
		
		//获取对应天打卡情况
		Map<String,String> params1 = new HashMap<String,String>();
		params1.put("readDate", dateStr);
		params1.put("userId", dkUser.getOpenid());
		DkReadPlanEntity readPlan = dkReadPlanService.queryUserReadPlanByIdAndDate(params1);
		if(null==readPlan){
			//return new JsonResult(-1,"您在今天没有阅读计划").toJson();
			//如果没有学习计划 判断是否需要生成新的学习计划，如果需要就立马生成
			int i = putPlanByOpenid(wxMpUser.getOpenId(), 210);
			if(i==-1){
				return new JsonResult(-1,"您在今天没有阅读计划").toJson();
			}
		}
		Map<String, Object> params = new HashMap<String, Object>();
		params.put("page", 1);
		params.put("limit", 1000);
		List<DkDomianEntity> domains  = dkDomianService.queryList(params);
		int r = (int)(Math.random()*domains.size());
    	String domain = domains.get(r).getDomainName().trim();
		String url = "http://"+domain;
		//获取当天阅读数据
		DkResourceEntity dr =  dkResourceService.queryObject(readPlan.getResourceId());
		dr.setShareTitle(dr.getShareTitle());
		result = new HashMap<String,Object>();
		result.put("resource", dr);
		result.put("read_plan", readPlan);
		result.put("domain", url);
		if(f){
			redisUtils.setObject("memread_"+openid+"_"+dateStr,result,7200);
		}
		return new JsonResult(200,"ok",result).toJson();
	}
	
	
	@RequestMapping(value="/plan/index")
	public String planIndex(@PathVariable String appid,String openid){
		WxMpUser wxMpUser = (WxMpUser) getSession().getAttribute(Constant.WX_USER);
		if(null==wxMpUser){
			return new JsonResult(24,"用户未登录，请先登录！").toJson();
		}
		
		DkUserEntity dkUser = dkUserService.queryObject(wxMpUser.getOpenId(),true);
		if(dkUser.getState()==0){
			return new JsonResult(23,"用户未订购，请跳转购买链接！").toJson();
		}
		
		openid = wxMpUser.getOpenId();
		String dateStr = DateUtils.format(new Date(), DateUtils.DATE_PATTERN);
		DkReadPlanEntity mem_readPlan = redisUtils.getObject("memdk_"+openid+"_"+dateStr);
		if(null!=mem_readPlan){
			//如果今天已经打过卡了，那么就读取新的缓存
			logger.info("=========>命中打卡缓存  : " + openid + " : " + wxMpUser.getOpenId());
			JSONObject object1 = redisUtils.getObject("memplandk_"+wxMpUser.getOpenId()+"_"+dateStr);
			if(null!=object1){
				return new JsonResult(200,"ok",object1).toJson();
			}
			
			JSONObject object = dkReadPlanService.planIndex(wxMpUser.getOpenId());
	    	redisUtils.setObject("memplandk_"+wxMpUser.getOpenId()+"_"+dateStr, object, 10000);
			return new JsonResult(200,"ok",object).toJson();
			
		}else{
			//如果没有打卡那么就读取就的缓存
			logger.info("=========>命中未打卡缓存  : " + openid + " : " + wxMpUser.getOpenId());
			//检查打卡情况
			Calendar cal = Calendar.getInstance();
			int h = cal.get(Calendar.HOUR_OF_DAY);
			if (h >=6 && h <= 8) {
				Map<String,String> params1 = new HashMap<String,String>();
				params1.put("readDate", dateStr);
				params1.put("userId", openid);
				DkReadPlanEntity readPlan = dkReadPlanService.queryUserReadPlanByIdAndDate(params1);
				if(null!=readPlan&&readPlan.getStatus()!=0){
					redisUtils.setObject("memdk_"+openid+"_"+dateStr,readPlan,7200);
					JSONObject object = dkReadPlanService.planIndex(wxMpUser.getOpenId());
					return new JsonResult(200,"ok",object).toJson();
				}
			}
			JSONObject object1 = redisUtils.getObject("memplanindex"+wxMpUser.getOpenId());
			if(null!=object1){
				return new JsonResult(200,"ok",object1).toJson();
			}
			JSONObject object = dkReadPlanService.planIndex(wxMpUser.getOpenId());
	    	redisUtils.setObject("memplanindex"+wxMpUser.getOpenId(), object, 7200);
			return new JsonResult(200,"ok",object).toJson();
		}
		
	}
	
	@RequestMapping(value="/plan/dk")
	public String planDk(@PathVariable String appid,String openid,@RequestParam(defaultValue="1")Integer source){
		if(StringUtils.isEmpty(openid)){
			return new JsonResult(-1,"openid不能为空").toJson(); 
		}
		try {
			String dateStr = DateUtils.format(new Date(), DateUtils.DATE_PATTERN);
			//判断缓存中是否有，如果有那么就是已经打卡完成了
			DkReadPlanEntity mem_readPlan = redisUtils.getObject("memdk_"+openid+"_"+dateStr);
			if(null!=mem_readPlan){
				return new JsonResult(200,"今天您已经完成打卡啦！").toJson(); 
			}
			//获取对应天打卡情况
			Map<String,String> params1 = new HashMap<String,String>();
			params1.put("readDate", dateStr);
			params1.put("userId", openid);
			DkReadPlanEntity readPlan = dkReadPlanService.queryUserReadPlanByIdAndDate(params1);
			if(null==readPlan){
				return new JsonResult(-1,"您在今天没有打卡计划").toJson();
			}
			if(readPlan.getStatus()!=0){
				return new JsonResult(200,"今天您已经完成打卡啦！").toJson(); 
			}else{
				readPlan.setReadtime(new Date());
				readPlan.setStatus(source);
				dkReadPlanService.update(readPlan);
				//完成打卡将数据set进对应的数据
				redisUtils.setObject("memdk_"+openid+"_"+dateStr,readPlan,7200);
			}
			//通过打卡处理用户付款问题
			//1、删除打卡缓存
			return new JsonResult(200,"打卡成功").toJson(); 
			
		} catch (Exception e) {
			e.printStackTrace();
			return new JsonResult(-1,"打卡失败").toJson(); 
		}
	}
	
	@RequestMapping(value="/share")
	public String share(@PathVariable String appid,String openid){
		try {
			if(StringUtils.isEmpty(openid)){
				return new JsonResult(-1,"openid不能为空").toJson(); 
			}
			UserReadDays readDays = redisUtils.getObject("memreadDays"+openid);
			if(null==readDays){
				readDays = dkReadPlanService.getUserReadDays(openid);
				redisUtils.setObject("memreadDays"+openid, readDays, 3600);
			}
			
			String url = redisUtils.getObject("memqrcode"+openid);
			logger.info("=========>命中二维码缓存成功 : " + openid + " : " + url);
			if(null==url||url.equals("")){
				WxMpService wxMpService = WxMpConfiguration.getMpServices().get(wxPayProperties.getAppId());//
				WxMpQrCodeTicket ticket = wxMpService.getQrcodeService().qrCodeCreateTmpTicket(openid, 2592000);
				url = ticket.getTicket();
				redisUtils.setObject("memqrcode"+openid, url, 2590000);
				logger.info("=========>生成二维码成功 : " + openid + " : " + url);
			}
			readDays.setQrcodeurl(url);
			return new JsonResult(200,"ok",readDays).toJson(); 
		} catch (Exception e) {
			e.printStackTrace();
			return new JsonResult(-1,"分享页面数据查询失败").toJson(); 
		}
	}
//	@RequestMapping(value="/qrc")
//	public void qrc(@PathVariable String appid,String content){
//		 //二维码中包含的信息
//	    try {
//			Map<EncodeHintType, Object> hints = new HashMap<EncodeHintType, Object>();
//			// 指定编码格式
//			hints.put(EncodeHintType.CHARACTER_SET, "UTF-8");
//			// 指定纠错级别(L--7%,M--15%,Q--25%,H--30%)
//			hints.put(EncodeHintType.ERROR_CORRECTION, ErrorCorrectionLevel.H);
//			// 编码内容,编码类型(这里指定为二维码),生成图片宽度,生成图片高度,设置参数
//			BitMatrix bitMatrix = new MultiFormatWriter().encode(content, BarcodeFormat.QR_CODE, 200, 200, hints);
//			//设置请求头
//			getResponse().setHeader("Content-Type","application/octet-stream");
//			getResponse().setHeader("Content-Disposition", "attachment;filename=" + "十二余的二维码.png");
//			OutputStream outputStream = getResponse().getOutputStream();
//			MatrixToImageWriter.writeToStream(bitMatrix, "png", outputStream);
//			outputStream.flush();
//			outputStream.close();
//		} catch (WriterException e) {
//			e.printStackTrace();
//		} catch (IOException e) {
//			e.printStackTrace();
//		}
//		
//	}
	
	
	
	
	
public int  putPlanByOpenid(String openid,int days){
		
		List<DkReadPlanEntity> list = dkReadPlanService.queryUserReadPlanById(openid);
		if(list.size()>=days){
			return -1;
		}
		DkReadPlanEntity tmp_p = list.get(list.size()-1);
		String last_read_date = tmp_p.getReadDate();
		Date last_read_date1 = DateUtils.strToDate1(last_read_date);
		int i = 1;
		while(true){
			DkReadPlanEntity readPlan = new DkReadPlanEntity();
			readPlan.setId(UUIDS.getUUID());
			readPlan.setCreatetime(new Date());
			readPlan.setReadDate(DateUtils.getDate(last_read_date1, i));
			readPlan.setResourceId(list.size()+i);
			readPlan.setStatus(0);
			readPlan.setUserId(openid);
			readPlan.setSendState(0);
			dkReadPlanService.save(readPlan);
			logger.info("===========>插入了 ：" + i );
			if(list.size()+i>=days){
				break;
			}
			i++;
		}
		return 0;
		
	}

}
